<template lang="pug">
  #mapContainer(ref='map')
</template>
<script>
export default {
  name: 'AMap',
  props: {
    lat: {
      type: Number,
      default: 0
    },
    lng: {
      type: Number,
      default: 0
    },
    address: {
      type: String,
      default: ''
    },
  },
  data () {
    return {
      info: {},
      AMap: {
        map: null,
        marker: null,
        geocoder: null,
        geolocation: null,
      }
    }
  },
  mounted () {
    this.initMap().then(() => {
      this.address ? this.addrToLatitude() : this.getAddress()
    })
  },
  methods: {
    initMap () {
      return new Promise((resolve, reject) => {
        this.newMap(resolve)
        this.mapTimer = setInterval(() => this.newMap(resolve), 200)
      })
    },
    newMap (resolve) {
      if (window.AMap) {
        if (!this.AMap.map) {
          this.AMap.map = new window.AMap.Map('mapContainer')

          this.AMap.map.plugin(['AMap.Geolocation', 'AMap.Geocoder'], () => {
            this.AMap.geocoder = new window.AMap.Geocoder()
            this.AMap.geolocation = new window.AMap.Geolocation({
              enableHighAccuracy: true, // 是否使用高精度定位，默认:true
              buttonOffset: new AMap.Pixel(10, 20), // 定位按钮与设置的停靠位置的偏移量，默认：Pixel(10, 20)
              buttonPosition: 'RB', // 定位按钮的停靠位置
              timeout: 10000, // 超过10秒后停止定位，默认：无穷大
              zoomToAccuracy: false, // 定位成功后是否自动调整地图视野到定位点
            })

            this.AMap.marker = new AMap.Marker() // 添加标记点

            this.AMap.map.add(this.AMap.marker)

            this.AMap.map.setZoom(14)

            this.AMap.map.on('click', this.handleMapClick) // click

            this.AMap.map.addControl(this.AMap.geolocation)

            resolve(this.AMap.map)
          })
        } else resolve(this.AMap.map)

        clearInterval(this.mapTimer)
        this.mapTimer = null

      }
    },

    handleMapClick (e) {
      let { lat, lng } = e.lnglat
      this.$emit('update:lng', lng)
      this.$emit('update:lat', lat)
      this.getAddress(lng, lat)
      this.AMap.marker.setPosition([lng, lat]) //更新点标记位置
    },

    getCurrentPosition () {
      return new Promise((resolve, reject) => {
        this.initMap().then(() => {
          this.AMap.geolocation.getCurrentPosition((status, res) => {
            if (status === 'complete') {
              let { lat, lng } = res.position
              resolve({ lat, lng })
              this.AMap.marker.setPosition([lng, lat]) //更新点标记位置
            } else {
              console.log('获取定位失败:', res)
              resolve()
            }
          })
        })
      })
    },

    async getAddress (lng, lat) {
      // 地址转换
      if (!lng) {
        let lnglat = await this.getCurrentPosition()
        if (lnglat) {
          this.$emit('update:lng', lnglat.lng)
          this.$emit('update:lat', lnglat.lat)
        }
      }
      return lng && new Promise((resolve, reject) => {
        this.initMap().then(() => {
          this.AMap.geocoder.getAddress([lng, lat], (status, res) => {
            if (status === 'complete') {
              console.log(res)
              this.$emit('update:address', res.regeocode.formattedAddress)
              resolve(res.regeocode)
            } else {
              console.log('地址转换失败:', res)
              resolve()
            }
          })
        })
      })
    },

    addrToLatitude () {
      if (!this.address) return
      this.AMap.geocoder.getLocation(this.address, (status, result) => {
        if (status === 'complete' && result.geocodes.length) {
          let { lat, lng } = result.geocodes[0].location
          this.$emit('update:lng', lng)
          this.$emit('update:lat', lat)
          this.AMap.marker.setPosition([lng, lat]); //更新点标记位置
          this.AMap.map.setZoomAndCenter(14, [lng, lat]);
        } else { console.log('地址转经纬 添加地图点失败:', result) }
      })
    },
  },
}
</script>
<style lang="stylus">
#mapContainer
  min-height 300px
</style>
